#include "modbus.h"
#include "usart.h"
#include "stm32f4xx_hal.h"
#include "main.h"
#include "tim.h"

#define Modbus_Address 0x01 //设置从机地址
/* 定义一个八位的线圈寄存器--------------------------------------------------------*/
uint8_t Modbus_IO[10000];
/* 定义一个16位的数据寄存器--------------------------------------------------------*/
uint16_t Reg[10000];//寄存器
/* 定义程序中需要使用的变量--------------------------------------------------------*/
uint8_t Modbus_Free;	//总线是否空闲标志位
uint8_t Modbus_Rx_Buff[20000];	//串口接受数据
uint8_t Modbus_Tx_Buff[20000];	//串口发送数据
uint8_t timer;	//定时器定时计数值，每1ms自增，超过4ms清零
uint16_t Rx_Cnt;	//串口接收数据长度，与Modbus_Rx_Buff[]一起使用
uint8_t finish;	//串口接收数据完成标志位，当定时器超过4ms没有采集到数据时会被置位
uint16_t Register_Adress; //寄存器地址
uint16_t calCRC;	//CRC校验的计算值
uint16_t realCRC;	//CRC校验的真实值，由串口接收到的数据计算而来
uint16_t Register_Num;	//寄存器数量
uint8_t Rx_Tmp_Buf;	//串口每一次接收到的数据，接收到赋给数组，不使用会造成数据丢失
/* CRC校验数组--------------------------------------------------------------------*/
const uint8_t auchCRCHi[] = { 
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40} ; 
/* CRC校验数组--------------------------------------------------------------------*/
const uint8_t auchCRCLo[] = { 
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 
0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 
0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 
0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 
0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 
0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 
0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 
0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, 
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,0x43, 0x83, 0x41, 0x81, 0x80, 0x40} ;
/*********************************************************************************/
//* 函数名：uint16_t CRC_Compute(uint8_t *puchMsg, uint16_t usDataLen)             
//* 入口参数：*puchMsg：需要进行CRC校验的数据数组								    
//*			 usDateLen：数据长度												  
//* 返回值：	一个16位CRC校验值		              								   
//* 函数功能：对输入的数据进行CRC校验							                    
/*********************************************************************************/
uint16_t CRC_Compute(uint8_t *puchMsg, uint16_t usDataLen) 
{ 
	uint8_t uchCRCHi = 0xFF ; 
	uint8_t uchCRCLo = 0xFF ; 
	uint32_t uIndex ; 
	while (usDataLen--) 
	{ 
		uIndex = uchCRCHi ^ *puchMsg++ ; 
		uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ; 
		uchCRCLo = auchCRCLo[uIndex] ; 
	} 
	return ((uchCRCHi<< 8)  | (uchCRCLo)) ; 
}
/*********************************************************************************/
//* 函数名：void Modbus_SendData(uint8_t *buff,uint8_t len)      			     
//* 入口参数：*buff：数组数据								 					  
//*			 len：数据长度														 
//* 返回值：	无		              												 
//* 函数功能：Modbus的串口发送函数								                  
/*********************************************************************************/
void Modbus_SendData(uint8_t *buff,uint8_t len)
{ 
	HAL_UART_Transmit(&huart1,buff,len,100);
}
/*********************************************************************************/
//* 函数名：void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)      	     
//* 入口参数：*huart：串口号 							 						  
//* 返回值：	无		              												 
//* 函数功能：串口接受的回调函数									                
/*********************************************************************************/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance==USART1)
	{
          if(finish!=0) return;
		if(Modbus_Free==0)//是不是首位数据
		{			
			Modbus_Free++;	//是首位数据就++
			Modbus_Rx_Buff[Rx_Cnt]=Rx_Tmp_Buf; //串口接收的数据放到数组的0位
			Rx_Cnt++;	//数组长度+1
			HAL_TIM_Base_Start_IT(&htim2);	//开启定时器2
			HAL_UART_Receive_IT(&huart1,(uint8_t*)&Rx_Tmp_Buf,1);	//开启下一次串口接收
		}
		else//不是首位数据
		{
			Modbus_Rx_Buff[Rx_Cnt]=Rx_Tmp_Buf;	//数据放到数组内
			Rx_Cnt++;	//数据长度+1
			HAL_UART_Receive_IT(&huart1,(uint8_t*)&Rx_Tmp_Buf,1);	//开启下一次数据接收
			__HAL_TIM_SET_COUNTER(&htim2,0); //复位定时器
		}

	}
}
/*********************************************************************************/
//* 函数名：void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)     	      
//* 入口参数：*htim：定时器x 							 						 													  */
//* 返回值：	无		              											
//* 函数功能：串定时器回调函数，定时时间1ms						                 
/*********************************************************************************/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  if(htim->Instance==TIM2)
  {
	  	timer++;
		if(timer>=10)	//达到4ms还没复位，说明数据接收完毕
		{
			Modbus_Free=0;	//总线空闲
            timer=0;	//定时值清零
			HAL_TIM_Base_Stop_IT(&htim2);//关定时器
			finish=1;	//接收数据完成标志位置位
			OSSemPost(DispSem_Run);
		}
  }
}
/*********************************************************************************/
//* 函数名：void Modbus_Service(void)  									 	      
//* 入口参数：无							 						  															
//* 返回值：	无		              												  
//* 函数功能：Modbus服务函数，对收到的数据代码进行判断解析						                  
/*********************************************************************************/
void Modbus_Service(void)
{
	if(finish!=1)//判断标志位是否被置位
	{
		return;
	}
	if(Modbus_Rx_Buff[0]!=Modbus_Address)	//判断地址
	{
		finish=0;
		Rx_Cnt=0;
		return;
	}
		if(Rx_Cnt<8)
	{
		finish=0;
		Rx_Cnt=0;
		return;
	}
        calCRC=CRC_Compute(Modbus_Rx_Buff,Rx_Cnt-2);	//获取传入数据的CRC校验值
        realCRC=(Modbus_Rx_Buff[Rx_Cnt-1])|((uint16_t)(Modbus_Rx_Buff[Rx_Cnt-2])<<8);	//计算传入的数据的CRC校验值
        if(realCRC!=calCRC)	//对比计算的CRC校验值和传入数据中的CRC校验值是否相同
	{       
          finish=0;
          Rx_Cnt=0;
          return;
        }
	if((Modbus_Rx_Buff[1]==0x01)||(Modbus_Rx_Buff[1]==0x03)||(Modbus_Rx_Buff[1]==0x0f)||(Modbus_Rx_Buff[1]==0x10))//判断功能码
	{
	    Register_Adress=(((uint16_t)Modbus_Rx_Buff[2])<<8|Modbus_Rx_Buff[3]);	
            switch (Modbus_Rx_Buff[1])	//判断功能码
            {
              case 0x01:
              {
              OSSemPost(DispSem_01);
              break;
              }
              case 0x03:
              {
                      OSSemPost(DispSem_03);
                      break;
              }
              case 0x0f:
              {
                      OSSemPost(DispSem_0f);
                      break;
              }
              case 0x10:
              {
                      OSSemPost(DispSem_10);;
                      break;
              }				
             }
        }
	else
	{
		Modbus_Tx_Buff[0]=Modbus_Rx_Buff[0];
		Modbus_Tx_Buff[1]=Modbus_Rx_Buff[1]|0x80;
		Modbus_Tx_Buff[2]=0x01;
		calCRC=CRC_Compute(Modbus_Tx_Buff,3);
		Modbus_Tx_Buff[3]=calCRC/256;
		Modbus_Tx_Buff[4]=calCRC%256;
		HAL_UART_Transmit(&huart1,Modbus_Tx_Buff,5,100);
		finish=0;
		Rx_Cnt=0;
		return;
	}
	finish=0;
}
/*********************************************************************************/
//* 函数名：void Modbus_01_Solve(void) 									 	      
//* 入口参数：无							 						  															
//* 返回值：	无		              												  
//* 函数功能：功能码1的操作函数，读线圈寄存器					                  
/*********************************************************************************/
void Modbus_01_Solve(void)
{
	uint16_t Byte_Num;//字节数
	uint16_t i;
	uint8_t Change[10000];
	Register_Num=(((uint16_t)Modbus_Rx_Buff[4])<<8|Modbus_Rx_Buff[5]);//寄存器数量
	if((Register_Adress+Register_Num)<=10000)
	{       
		if((Register_Num>=0x0001)&(Register_Num<=0x07d0))
		{
			if(Rx_Cnt!=8)
			{
			Rx_Cnt=0;
			return;
			}
			Modbus_Tx_Buff[0]=Modbus_Rx_Buff[0];
			Modbus_Tx_Buff[1]=Modbus_Rx_Buff[1];
			Byte_Num=Register_Num/8; //除8取除数看看有几个字节
			if(Register_Num%8!=0) Byte_Num+=1;  //如果除8看余数不得0，说明有余数，需要再加一位放余数
			Modbus_Tx_Buff[2]=Byte_Num;
			for(i=0;i<Register_Num;i++)
			{
				if(i%8==0) Modbus_Tx_Buff[3+i/8]=0x00;
				Change[Register_Adress+i]=Modbus_IO[Register_Adress+i];
				Modbus_Tx_Buff[3+i/8]>>=1;
				Modbus_Tx_Buff[3+i/8]|=((Change[Register_Adress+i])<<7)&0x80;
				if(i==Register_Num-1) 
				{
					if(Register_Num%8) Modbus_Tx_Buff[3+i/8]>>=8-(Register_Num%8);
				}
			}
			calCRC=CRC_Compute(Modbus_Tx_Buff,3+Byte_Num);	//计算CRC校验值并
			Modbus_Tx_Buff[Byte_Num+3]=calCRC/256;	//放到数组内
			Modbus_Tx_Buff[Byte_Num+4]=calCRC%256;
			HAL_UART_Transmit(&huart1,Modbus_Tx_Buff,Byte_Num+5,100);
		}
		else
		{
			Modbus_Tx_Buff[0]=Modbus_Rx_Buff[0];
			Modbus_Tx_Buff[1]=Modbus_Rx_Buff[1]|0x80;
			Modbus_Tx_Buff[2]=0x03;
			calCRC=CRC_Compute(Modbus_Tx_Buff,3);
			Modbus_Tx_Buff[3]=calCRC/256;
			Modbus_Tx_Buff[4]=calCRC%256;
			HAL_UART_Transmit(&huart1,Modbus_Tx_Buff,5,100);
		}
	}
	else
	{
		//错误码
		Modbus_Tx_Buff[0]=Modbus_Rx_Buff[0];
		Modbus_Tx_Buff[1]=Modbus_Rx_Buff[1]|0x80;
		Modbus_Tx_Buff[2]=0x02;
		calCRC=CRC_Compute(Modbus_Tx_Buff,3);
		Modbus_Tx_Buff[3]=calCRC/256;
		Modbus_Tx_Buff[4]=calCRC%256;
		HAL_UART_Transmit(&huart1,Modbus_Tx_Buff,5,100);	
	}
        Rx_Cnt=0;
}
/*********************************************************************************/
//* 函数名：void Modbus_0f_Solve(void) 									 	      
//* 入口参数：无							 						  															
//* 返回值：	无		              												  
//* 函数功能：功能码0f的操作函数，写多个线圈寄存器					                  
/*********************************************************************************/
void Modbus_0f_Solve(void)
{
	uint16_t i;
	uint16_t Byte_Num;
        Register_Num=(((uint16_t)Modbus_Rx_Buff[4])<<8|Modbus_Rx_Buff[5]);//算寄存器数量
        Byte_Num=Register_Num/8;
	if(Register_Num%8!=0) Byte_Num+=1;
	if((Register_Num>=1)&(Register_Num<=0x07b0)&(Byte_Num==Modbus_Rx_Buff[6]))
	{
		if((Register_Adress+Register_Num)<=10000)
		{
			if(Modbus_Rx_Buff[6]!=Rx_Cnt-9)
			{
			Rx_Cnt=0;
			return;
			}
			for(i=0;i<Register_Num;i++)
			{
				if(Modbus_Rx_Buff[7+i/8]&0x01) Modbus_IO[Register_Adress+i]=0x01;
				else Modbus_IO[Register_Adress+i]=0x00;
				Modbus_Rx_Buff[7+i/8]>>=1; //接收到数据右移，次低位变最低位
			}
			Modbus_Tx_Buff[0]=Modbus_Rx_Buff[0];
			Modbus_Tx_Buff[1]=Modbus_Rx_Buff[1];
			Modbus_Tx_Buff[2]=Modbus_Rx_Buff[2];
			Modbus_Tx_Buff[3]=Modbus_Rx_Buff[3];
			Modbus_Tx_Buff[4]=Modbus_Rx_Buff[4];
			Modbus_Tx_Buff[5]=Modbus_Rx_Buff[5];
			calCRC=CRC_Compute(Modbus_Tx_Buff,6);
			Modbus_Tx_Buff[6]=calCRC/256;
			Modbus_Tx_Buff[7]=calCRC%256;
			HAL_UART_Transmit(&huart1,Modbus_Tx_Buff,8,100);
		}
		else
		{
			Modbus_Tx_Buff[0]=Modbus_Rx_Buff[0];
			Modbus_Tx_Buff[1]=Modbus_Rx_Buff[1]|0x80;
			Modbus_Tx_Buff[2]=0x02;
                        calCRC=CRC_Compute(Modbus_Tx_Buff,3);
			Modbus_Tx_Buff[3]=calCRC/256;
			Modbus_Tx_Buff[4]=calCRC%256;
			HAL_UART_Transmit(&huart1,Modbus_Tx_Buff,5,100);	
		}
	}
	else
	{
		Modbus_Tx_Buff[0]=Modbus_Rx_Buff[0];
		Modbus_Tx_Buff[1]=Modbus_Rx_Buff[1]|0x80;
		Modbus_Tx_Buff[2]=0x03;
		calCRC=CRC_Compute(Modbus_Tx_Buff,3);
		Modbus_Tx_Buff[3]=calCRC/256;
		Modbus_Tx_Buff[4]=calCRC%256;
		HAL_UART_Transmit(&huart1,Modbus_Tx_Buff,5,100);
	}
        Rx_Cnt=0;
}
/*********************************************************************************/
//* 函数名：void Modbus_03_Solve(void) 									 	      
//* 入口参数：无							 						  															
//* 返回值：	无		              												  
//* 函数功能：功能码03的操作函数，读寄存器的值					                  
/*********************************************************************************/
void Modbus_03_Solve(void)
{
	uint16_t i;
	Register_Num=(((uint16_t)Modbus_Rx_Buff[4])<<8|Modbus_Rx_Buff[5]);//计算寄存器数量
	if((Register_Num>=0x0001)&(Register_Num<=0x007d))
	{
		if((Register_Adress+Register_Num)<=10000)
		{
			if(Rx_Cnt!=8)
			{
			Rx_Cnt=0;
			return;
			}
			Modbus_Tx_Buff[0]=Modbus_Rx_Buff[0];
			Modbus_Tx_Buff[1]=Modbus_Rx_Buff[1];
			Modbus_Tx_Buff[2]=Register_Num*2;	//返回字节数，因为寄存器是一个16位的，等于2个字节，因此要乘2
			for(i=0;i<Register_Num;i++)
			{
				Modbus_Tx_Buff[i*2+3]=Reg[Register_Adress+i]/256;	//将要读的寄存高8位放入发送数组中
				Modbus_Tx_Buff[i*2+4]=Reg[Register_Adress+i]%256;	//将要读的寄存低8位放入发送数组中
			}
			calCRC=CRC_Compute(Modbus_Tx_Buff,Register_Num*2+3);
			Modbus_Tx_Buff[Register_Num*2+3]=calCRC/256;
			Modbus_Tx_Buff[Register_Num*2+4]=calCRC%256;
			HAL_UART_Transmit(&huart1,Modbus_Tx_Buff,Register_Num*2+5,100);
		}
		else
		{
			Modbus_Tx_Buff[0]=Modbus_Rx_Buff[0];
			Modbus_Tx_Buff[1]=Modbus_Rx_Buff[1]|0x80;
			Modbus_Tx_Buff[2]=0x02;
			calCRC=CRC_Compute(Modbus_Tx_Buff,3);
			Modbus_Tx_Buff[3]=calCRC/256;
			Modbus_Tx_Buff[4]=calCRC%256;
			HAL_UART_Transmit(&huart1,Modbus_Tx_Buff,5,100);	
		}
	}
	else
	{
		Modbus_Tx_Buff[0]=Modbus_Rx_Buff[0];
		Modbus_Tx_Buff[1]=Modbus_Rx_Buff[1]|0x80;
		Modbus_Tx_Buff[2]=0x03;
		calCRC=CRC_Compute(Modbus_Tx_Buff,3);
		Modbus_Tx_Buff[3]=calCRC/256;
		Modbus_Tx_Buff[4]=calCRC%256;
		HAL_UART_Transmit(&huart1,Modbus_Tx_Buff,5,100);
	}
	Rx_Cnt=0;
}
/*********************************************************************************/
//* 函数名：void Modbus_10_Solve(void) 									 	      
//* 入口参数：无							 						  															
//* 返回值：	无		              												  
//* 函数功能：功能码10的操作函数，写多个寄存器					                  
/*********************************************************************************/
void Modbus_10_Solve(void)
{
	uint16_t i;
	Register_Num=(((uint16_t)Modbus_Rx_Buff[4])<<8|Modbus_Rx_Buff[5]);//计算寄存器数量
	if((Register_Num>=0x0001)&(Register_Num<=0x007b)&(Modbus_Rx_Buff[6]==Register_Num*2))
	{
		if((Register_Adress+Register_Num)<=10000)
		{
			if((Rx_Cnt-9)!=Modbus_Rx_Buff[6])
			{
			Rx_Cnt=0;
			return;
			}
			for(i=0;i<Register_Num;i++)
			{
				//收到的数据中字节高位取出*256到高八位，或上数据中低字节的八位，最后放到寄存器中
				Reg[Register_Adress+i]=(uint16_t)((Modbus_Rx_Buff[7+i*2])*256|Modbus_Rx_Buff[8+i*2]);
			}
			Modbus_Tx_Buff[0]=Modbus_Rx_Buff[0];
			Modbus_Tx_Buff[1]=Modbus_Rx_Buff[1];
			Modbus_Tx_Buff[2]=Modbus_Rx_Buff[2];
			Modbus_Tx_Buff[3]=Modbus_Rx_Buff[3];
			Modbus_Tx_Buff[4]=Modbus_Rx_Buff[4];
			Modbus_Tx_Buff[5]=Modbus_Rx_Buff[5];
			calCRC=CRC_Compute(Modbus_Tx_Buff,6);
			Modbus_Tx_Buff[6]=calCRC/256;
			Modbus_Tx_Buff[7]=calCRC%256;
			HAL_UART_Transmit(&huart1,Modbus_Tx_Buff,8,100);
		}
		else
		{
			Modbus_Tx_Buff[0]=Modbus_Rx_Buff[0];
			Modbus_Tx_Buff[1]=Modbus_Rx_Buff[1]|0x80;
			Modbus_Tx_Buff[2]=0x02;
			calCRC=CRC_Compute(Modbus_Tx_Buff,3);
			Modbus_Tx_Buff[3]=calCRC/256;
			Modbus_Tx_Buff[4]=calCRC%256;
			HAL_UART_Transmit(&huart1,Modbus_Tx_Buff,5,100);	
		}
	}
	else
	{
		Modbus_Tx_Buff[0]=Modbus_Rx_Buff[0];
		Modbus_Tx_Buff[1]=Modbus_Rx_Buff[1]|0x80;
		Modbus_Tx_Buff[2]=0x03;
		calCRC=CRC_Compute(Modbus_Tx_Buff,3);
		Modbus_Tx_Buff[3]=calCRC/256;
		Modbus_Tx_Buff[4]=calCRC%256;
		HAL_UART_Transmit(&huart1,Modbus_Tx_Buff,5,100);
	}
	Rx_Cnt=0;
}
